﻿<template>
  <div class="categories-wrap">
    <div class="categories-box">
      <div class="categories-container flex-row">
        <div style="border-right: 1px solid #ccc;">
          <div class="buttons-box filter-container">
            <el-button :icon="`iconfont icon-${btn.icon}`" :type="btn.class" size="mini" v-for="btn of categoryBtns" v-bind:key="btn.Id" class="filter-item" @click="onBtnClicked(btn.btnCode)">{{btn.name}}</el-button>
            <div @keyup.13="handleSearchCategoryTypes">
              <el-input placeholder="请输入内容" v-model="typesListQuery.key" size="mini" style="margin-top: 10px;width: 130px;">
                <i slot="prefix" class="el-input__icon el-icon-search"></i>
              </el-input>
              <el-button class="filter-item" size="mini" v-waves icon="el-icon-search" @click="handleSearchCategoryTypes">搜索</el-button>
            </div>
          </div>
          <el-card shadow="never" class="body-small categories-menu-card">
            <div slot="header" class="clearfix">
              <el-button type="text" style="padding: 0 11px" @click="getAllCategories">全部字典>></el-button>
            </div>
            <el-tree :current-node-key="listQuery.TypeId" node-key="id" :highlight-current="true" @node-click="handleNodeClick" :data="categoryTypes" :expand-on-click-node="false" default-expand-all :props="categoryTypeProps">
              <span class="custom-tree-node" slot-scope="{ node }">
                <span><i class="el-icon-menu" style="margin-right: 10px;"></i>{{ node.label }}</span>
              </span>
            </el-tree>
          </el-card>
        </div>
        <el-main class="categories-content flex-item">
          <sticky :className="'sub-navbar'">
            <div class="filter-container" style="white-space: nowrap; overflow-x: auto;">
              <el-input @keyup.enter.native="handleFilter" size="mini" style="width: 200px;" class="filter-item" :placeholder="'名称'" v-model="listQuery.key">
              </el-input>

              <el-button size="mini" icon="el-icon-search" @click="handleFilter">搜索</el-button>
              <el-button type="primary" size="mini" v-if="checkPermission('category', 'btnAdd')" icon="el-icon-plus" @click="onBtnClicked('btnAdd')">新增</el-button>
              <el-button type="warning" size="mini" v-if="checkPermission('category', 'btnEdit')" icon="el-icon-edit" @click="onBtnClicked('btnEdit')">编辑</el-button>
              <el-button type="danger" size="mini" v-if="checkPermission('category', 'btnDel')" icon="el-icon-delete" @click="onBtnClicked('btnDel')">删除</el-button>

            </div>
          </sticky>
          <el-table height="calc(100% - 52px - 44px)" ref="mainTable" :key='tableKey' :data="list" v-loading="listLoading" border fit highlight-current-row style="width: 100%;" @row-click="rowClick"
            @selection-change="handleSelectionChange">
            <el-table-column type="selection" align="center" width="55"></el-table-column>

            <el-table-column prop="dtCode" min-width="150" label="分类标识" show-overflow-tooltip></el-table-column>
            <el-table-column prop="name" min-width="150" label="分类名称" show-overflow-tooltip></el-table-column>
            <el-table-column prop="dtValue" min-width="150" label="分类值" show-overflow-tooltip></el-table-column>

            <el-table-column prop="createTime" min-width="170" label="创建时间" show-overflow-tooltip></el-table-column>
            <el-table-column prop="createUserName" min-width="170" label="创建人" show-overflow-tooltip></el-table-column>

          </el-table>
          <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="handleCurrentChange" />
        </el-main>
      </div>
      <el-dialog :destroy-on-close="true" class="dialog-mini custom-dialog user-dialog" width="400px" title="添加分组" :visible.sync="addTypesDialog">
        <el-form ref="categoryTypeForm" :model="categoryTypesInfo" :rules="categoryRules" el="categorys-tayps-form" label-width="80px">
          <el-form-item prop="id" label="分类id">
            <el-input size="small" v-model="categoryTypesInfo.id"></el-input>
          </el-form-item>
          <el-form-item prop="name" label="分类名称">
            <el-input size="small" v-model="categoryTypesInfo.name"></el-input>
          </el-form-item>
        </el-form>
        <div style="text-align:right;margin-top: 10px;">
          <el-button size="small" type="cancel" @click="addTypesDialog = false">取消</el-button>
          <el-button size="small" type="primary" @click="handleAddCategories">确定</el-button>
        </div>
      </el-dialog>
      <el-dialog v-el-drag-dialog class="dialog-mini" width="500px" :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
        <el-form :rules="rules" ref="dataForm" :model="temp" label-position="right" label-width="100px">
          <el-form-item size="small" :label="'Id'" prop="id">
            <el-input v-model="temp.id" :disabled="true" placeholder="系统自动处理"></el-input>
          </el-form-item>

          <el-form-item size="small" :label="'分类标识'" prop="dtCode">
            <el-input v-model="temp.dtCode"></el-input>
          </el-form-item>

          <el-form-item size="small" :label="'名称'" prop="name">
            <el-input v-model="temp.name"></el-input>
          </el-form-item>

          <el-form-item size="small" :label="'值'" prop="dtValue">
            <el-input v-model="temp.dtValue"></el-input>
          </el-form-item>

          <el-form-item size="small" :label="'是否可用'" prop="enable">
            <el-select class="filter-item" v-model="temp.enable" placeholder="Please select">
              <el-option v-for="item in  statusOptions" :key="item.key" :label="item.display_name" :value="item.key">
              </el-option>
            </el-select>
          </el-form-item>

          <el-form-item size="small" :label="'排序号'">
            <el-input-number v-model="temp.sortNo" :min="0" :max="10"></el-input-number>
          </el-form-item>

          <el-form-item size="small" :label="'描述'" prop="description">
            <el-input v-model="temp.description"></el-input>
          </el-form-item>

          <el-form-item size="small" :label="'所属分类ID'" prop="typeId">
            <el-select v-model="temp.typeId">
              <el-option v-for="(item, index) in categoryTypes" :key="index" :value="item.id" :label="item.name"></el-option>
            </el-select>
          </el-form-item>
        </el-form>
        <div slot="footer">
          <el-button size="mini" @click="dialogFormVisible = false">取消</el-button>
          <el-button size="mini" v-if="dialogStatus=='create'" type="primary" @click="createData">确认</el-button>
          <el-button size="mini" v-else type="primary" @click="updateData">确认</el-button>
        </div>
      </el-dialog>
    </div>
  </div>
</template>

<script>
import { mapGetters } from "vuex";
import extend from "@/extensions/delRows.js";
import * as categorys from "@/api/categorys";
import waves from "@/directive/waves"; // 水波纹指令
import Sticky from "@/components/Sticky";
import Pagination from "@/components/Pagination";
import elDragDialog from "@/directive/el-dragDialog";
export default {
  name: "category",
  components: { Sticky, Pagination },
  mixins: [extend],
  directives: {
    waves,
    elDragDialog,
  },
  data() {
    return {
      multipleSelection: [], // 列表checkbox选中的值
      tableKey: 0,
      list: null,
      total: 0,
      listLoading: true,
      listQuery: {
        // 查询条件
        page: 1,
        limit: 20,
        key: undefined,
        TypeId: undefined,
      },
      statusOptions: [
        { key: true, display_name: "正常" },
        { key: false, display_name: "停用" },
      ],
      temp: {
        id: "", // 分类表ID（可作为分类的标识）
        dtCode: "",
        name: "", // 名称
        dtValue: "",
        enable: true, // 是否可用
        sortNo: "", // 排序号
        description: "", // 分类描述
        typeId: "", // 分类类型ID
        extendInfo: "", // 其他信息,防止最后加逗号，可以删除
      },
      dialogFormVisible: false,
      dialogStatus: "",
      textMap: {
        update: "编辑",
        create: "添加",
      },
      dialogPvVisible: false,
      pvData: [],
      rules: {
        appId: [
          {
            required: true,
            message: "必须选择一个应用",
            trigger: "change",
          },
        ],
        name: [
          {
            required: true,
            message: "名称不能为空",
            trigger: "blur",
          },
        ],
      },
      downloadLoading: false,
      headerList: [],
      searchCategories: "", // 分类搜索
      addTypesDialog: false,
      categoryTypes: [],
      searchCategoryType: "",
      categoryTypesInfo: {
        id: "",
        name: "",
      },
      categoryRules: {
        name: [
          {
            required: true,
            message: "分类名称不能为空",
            trigger: "blur",
          },
        ],
        id: [
          {
            required: true,
            message: "分类id不能为空",
            trigger: "blur",
          },
        ],
      },
      categoryTypeProps: {
        children: "children",
        label: "name",
      },
      typesListQuery: {
        page: 1,
        limit: 99999,
        key: "",
      },
    };
  },
  filters: {
    statusFilter(disable) {
      const statusMap = {
        false: "color-success",
        true: "color-danger",
      };
      return statusMap[disable];
    },
  },
  computed: {
    // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters(["modulesTree"]),
    categoryBtns() {
      var route = this.$route;
      var elements = route.meta.elements;
      elements =
        elements &&
        elements.length > 0 &&
        elements
          .filter(
            (item) =>
              item.btnCode === "btnDelCategory" ||
              item.btnCode === "btnAddCategory"
          )
          .sort((a, b) => {
            return a.sort - b.sort;
          });
      return elements || [];
    },
    typesBtns() {
      var route = this.$route;
      var elements = route.meta.elements;
      elements =
        elements &&
        elements.length > 0 &&
        elements
          .filter(
            (item) =>
              item.btnCode !== "btnDelCategory" &&
              item.btnCode !== "btnAddCategory" &&
              item.btnCode !== "btnRefresh"
          )
          .sort((a, b) => {
            return a.sort - b.sort;
          });
      return elements || [];
    },
    isShowOperation() {
      const route = this.$route;
      const elements = route.meta.elements || [];
      let flag = false;
      elements.forEach((item) => {
        if (item.btnCode === "btnEdit") {
          flag = true;
        }
      });
      return flag;
    },
  },
  created() {
    this.getList();
    this.loadCategoryTypes();
  },
  methods: {
    getAllCategories() {
      this.listQuery.TypeId = "";
      this.listQuery.page = 1;
      this.getList();
    },
    rowClick(row) {
      this.$refs.mainTable.clearSelection();
      this.$refs.mainTable.toggleRowSelection(row);
    },
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },
    onBtnClicked: function (btnCode) {
      console.log("you click:" + btnCode);
      switch (btnCode) {
        case "btnAdd":
          this.handleCreate();
          break;
        case "btnEdit":
          if (this.multipleSelection.length !== 1) {
            this.$message({
              message: "只能选中一个进行编辑",
              type: "error",
            });
            return;
          }
          this.handleUpdate(this.multipleSelection[0]);
          break;
        case "btnDel":
          if (this.multipleSelection.length < 1) {
            this.$message({
              message: "至少删除一个",
              type: "error",
            });
            return;
          }
          this.handleDelete(this.multipleSelection);
          break;
        case "btnAddCategory":
          this.addTypesDialog = true;
          break;
        case "btnDelCategory":
          this.handleDeleteCategories();
          break;
        default:
          break;
      }
    },
    getList() {
      this.listLoading = true;
      categorys.getList(this.listQuery).then((res) => {
        this.list = res.result;
        this.total = res.count;
        this.listLoading = false;
      });
    },
    handleFilter() {
      this.listQuery.page = 1;
      this.getList();
    },
    handleSizeChange(val) {
      this.listQuery.limit = val;
      this.getList();
    },
    handleCurrentChange(val) {
      this.listQuery.page = val.page;
      this.listQuery.limit = val.limit;
      this.getList();
    },
    resetTemp() {
      this.temp = {
        id: "",
        name: "",
        enable: true,
        dtCode: "",
        dtValue: "",
        sortNo: "",
        description: "",
        typeId: "",
        extendInfo: "",
      };
    },
    handleCreate() {
      // 弹出添加框
      this.resetTemp();
      this.dialogStatus = "create";
      this.dialogFormVisible = true;
      this.$nextTick(() => {
        this.$refs["dataForm"].clearValidate();
      });
    },
    createData() {
      // 保存提交
      this.$refs["dataForm"].validate((valid) => {
        if (valid) {
          categorys.add(this.temp).then(() => {
            this.list.unshift(this.temp);
            this.dialogFormVisible = false;
            this.$notify({
              title: "成功",
              message: "创建成功",
              type: "success",
              duration: 2000,
            });
          });
        }
      });
    },
    handleUpdate(row) {
      // 弹出编辑框
      this.temp = Object.assign({}, row); // copy obj
      this.dialogStatus = "update";
      this.dialogFormVisible = true;
      this.$nextTick(() => {
        this.$refs["dataForm"].clearValidate();
      });
    },
    updateData() {
      // 更新提交
      this.$refs["dataForm"].validate((valid) => {
        if (valid) {
          const tempData = Object.assign({}, this.temp);
          categorys.update(tempData).then(() => {
            for (const v of this.list) {
              if (v.id === this.temp.id) {
                const index = this.list.indexOf(v);
                this.list.splice(index, 1, this.temp);
                break;
              }
            }
            this.dialogFormVisible = false;
            this.$notify({
              title: "成功",
              message: "更新成功",
              type: "success",
              duration: 2000,
            });
          });
        }
      });
    },
    handleDelete(rows) {
      // 多行删除
      this.delrows(categorys, rows);
    },
    // 添加分类
    handleAddCategories() {
      this.$refs["categoryTypeForm"].validate((valid) => {
        if (valid) {
          categorys.addType(this.categoryTypesInfo).then(() => {
            this.$notify({
              title: "成功",
              message: "添加成功",
              type: "success",
              duration: 2000,
            });
            this.addTypesDialog = false;
            this.categoryTypes.push(this.categoryTypesInfo);
          });
        }
      });
    },
    // 删除分类
    handleDeleteCategories() {
      if (!this.listQuery.TypeId) {
        this.$message({
          message: "请选择需要删除的分类",
          type: "error",
        });
        return;
      }
      const ids = [this.listQuery.TypeId];
      categorys.delType(ids).then(() => {
        this.$notify({
          title: "成功",
          message: "删除成功",
          type: "success",
          duration: 2000,
        });
        this.categoryTypes = this.categoryTypes.filter(
          (item) => item.id !== this.listQuery.TypeId
        );
      });
    },
    // 搜索分类
    handleSearchCategoryTypes() {
      this.typesListQuery.page = 1;
      this.loadCategoryTypes();
    },
    // 获取分类列表
    loadCategoryTypes() {
      categorys.loadType(this.typesListQuery).then((res) => {
        this.categoryTypes = [...res.result];
      });
    },
    handleNodeClick(val) {
      this.listQuery.TypeId = val.id;
      this.getList();
    },
  },
};
</script>
<style rel="stylesheet/scss" lang="scss">
.dialog-mini .el-select {
  width: 100%;
}
.categories-wrap {
  width: 100%;
  height: calc(100vh - 84px);
  box-sizing: border-box;
  padding: 10px;
  .categories-menu-card {
    height: calc(100% - 86px);
    overflow: auto;
    .el-card__body {
      height: auto;
    }
  }
}
.categories-box {
  height: 100%;
  background: #fff;
  box-sizing: border-box;
  .categories-container {
    width: 100%;
    height: 100%;
    border: 1px solid #ccc;
    box-sizing: border-box;
    position: relative;
    .categories-item {
      height: 30px;
      line-height: 30px;
      padding: 0 10px !important;
    }
  }
  .buttons-box {
    padding: 10px 10px;
    background: #f5f5f5;
  }
  .categories-content {
    height: 100%;
    padding: 0;
    .buttons-box {
      text-align: right;
    }
  }
}
</style>
